/*
 * Copyright (c) 1995 Danny Gasparovski.
 *
 * Please read the file COPYRIGHT for the
 * terms and conditions of the copyright.
 */

#include "qemu-common.h"
#include <slirp.h>
#include "ip_icmp.h"
#ifdef __sun__
#include <sys/filio.h>
#endif

static void sofcantrcvmore(struct socket *so);
static void sofcantsendmore(struct socket *so);

struct socket *
solookup(struct socket *head, struct in_addr laddr, u_int lport,
         struct in_addr faddr, u_int fport)
{
	struct socket *so;

	for (so = head->so_next; so != head; so = so->so_next) {
		if (so->so_lport == lport &&
		    so->so_laddr.s_addr == laddr.s_addr &&
		    so->so_faddr.s_addr == faddr.s_addr &&
		    so->so_fport == fport)
		   break;
	}

	if (so == head)
	   return (struct socket *)NULL;
	return so;

}

/*
 * Create a new socket, initialise the fields
 * It is the responsibility of the caller to
 * insque() it into the correct linked-list
 */
struct socket *
socreate(Slirp *slirp)
{
  struct socket *so;

  so = (struct socket *)malloc(sizeof(struct socket));
  if(so) {
    memset(so, 0, sizeof(struct socket));
    so->so_state = SS_NOFDREF;
    so->s = -1;
    so->slirp = slirp;
    so->pollfds_idx = -1;
  }
  return(so);
}

/*
 * remque and free a socket, clobber cache
 */
void
sofree(struct socket *so)
{
  Slirp *slirp = so->slirp;

  if (so->so_emu==EMU_RSH && so->extra) {
	sofree(so->extra);
	so->extra=NULL;
  }
  if (so == slirp->tcp_last_so) {
      slirp->tcp_last_so = &slirp->tcb;
  } else if (so == slirp->udp_last_so) {
      slirp->udp_last_so = &slirp->udb;
  } else if (so == slirp->icmp_last_so) {
      slirp->icmp_last_so = &slirp->icmp;
  }
  m_free(so->so_m);

  if(so->so_next && so->so_prev)
    remque(so);  /* crashes if so is not in a queue */

  free(so);
}

/*
 * Write data from so_rcv to so's socket,
 * updating all sbuf field as necessary
 */
int
sowrite(struct socket *so)
{
	int  n,nn;
	struct sbuf *sb = &so->so_rcv;
	int len = sb->sb_cc;

	return nn;
}

